#ifndef __EVENTLOOP_H_
#define __EVENTLOOP_H_

#include "TcpConnection.hpp"
#include "MutexLock.hpp"
#include <vector>
#include <map>

using std::vector;
using std::map;

namespace ln{

class Acceptor;

using Functor = std::function<void()>;

class EventLoop{
public:
    EventLoop(Acceptor &);
    ~EventLoop();
    void setAllCallbacks(Callback && cb1,Callback && cb2,Callback && cb3){
        _onConnection = std::move(cb1);
        _onMessage = std::move(cb2);
        _onClose = std::move(cb3);
    }
    void loop();
    void unloop();
    
    void runInLoop(Functor &&);

private:
    int createEpollFd();
    void addEpollReadEvent(int);
    void delEpollReadEvent(int);
    void waitEpollFd();
    void handleNewConnection();
    void handleMessage(int);

    int createEventFd();
    void handleReadEvent();
    void wakeup();
    void doPendingFunctors();

private:
    int                        _epfd;
    int                        _eventfd;

    Acceptor &                 _acceptor;
    bool                       _isLooping;
    vector<struct epoll_event> _evtArr;
    map<int,TcpConnectionPtr>  _conns;

    Callback                   _onConnection;
    Callback                   _onMessage;
    Callback                   _onClose;
    
    vector<Functor>            _pendingFunctors;
    MutexLock                  _mutex;
};

}//end of namespace ln

#endif

